package gorilla

import (
	"demo/web/websocket/gorilla/net"
	message2 "demo/web/websocket/message"
	"encoding/json"
	"fmt"

	"github.com/gin-gonic/gin"

	ws "github.com/gorilla/websocket"
)

func GorillaChatServer() {
	engine := gin.Default()

	engine.GET("/hello", func(context *gin.Context) {
		context.JSON(200, "hello")
	})
	engine.Static("/static", "/Users/myselffan/projects-test/go/go-demo/web/websocket/static")
	engine.GET("/chat", websocketChatServer)

	engine.Run(":8080")
}

var (
	upgrader2 = ws.Upgrader{}
	manager   = net.NewGorillaManager()
)

func websocketChatServer(context *gin.Context) {
	if ws.IsWebSocketUpgrade(context.Request) {
		request := context.Request
		responseWriter := context.Writer
		conn, err := upgrader2.Upgrade(responseWriter, request, responseWriter.Header())
		if err != nil {
			panic(err)
		}

		webSocketHandler(conn)
	}
}

func webSocketHandler(conn *ws.Conn) {
	for {
		/**
		websocket error:
		websocket: close 1001 (going away)
		websocket: close 3002: logout
		*/
		_, data, err := conn.ReadMessage()
		if err != nil {
			fmt.Println("read error, error=" + err.Error())

			//连接异常  关闭连接 跳出循环
			uid := manager.GetUid(conn)
			if uid != "" {
				manager.DelConn(uid, conn)
				fmt.Println("websocket disconnected, conn=" + conn.RemoteAddr().String() + ", uid=" + uid)

				msg := uid + "退出了直播间"
				sendGroupMessage(msg)
			}

			err = conn.Close()
			if err != nil {
				fmt.Println("close connection failed, conn=" + conn.RemoteAddr().String() + ", uid=" + uid)
				panic(err)
			}

			break
		}

		//群发消息
		processMessage(data, conn)
	}
}

func processMessage(message []byte, conn *ws.Conn) {
	var chatMessage = message2.ChatMessage{}

	err := json.Unmarshal(message, &chatMessage)
	if err != nil {
		fmt.Println(err.Error())
		return
	}

	switch chatMessage.Type {
	case 1:
		manager.AddConn(chatMessage.Uid, conn)
		fmt.Println("websocket connected, addr=" + conn.RemoteAddr().String() + ", uid=" + chatMessage.Uid)

		text := chatMessage.Uid + "进入了直播间"
		sendGroupMessage(text)
	case 2:
		text := chatMessage.Uid + "退出了直播间"
		sendGroupMessage(text)

		manager.DelConn(chatMessage.Uid, conn)
		fmt.Println("websocket disconnected, addr=" + conn.RemoteAddr().String() + ", uid=" + chatMessage.Uid)
	case 3:
		sendGroupMessage(chatMessage.Uid + ": " + chatMessage.Text)
	}
}

func sendGroupMessage(message string) {
	data := []byte(message)
	for conn := range manager.Conns {
		conn.WriteMessage(ws.TextMessage, data)
	}
}
